package com.guldan.jaina.manager;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;

import com.guldan.core.constants.CommonConstant;
import com.guldan.core.enums.UploadTypeEn;
import com.guldan.core.exception.BusinessException;
import com.guldan.jaina.dto.progress.BarDTO;
import com.guldan.jaina.dto.projectextensiondic.ProjectExtensionDicDTO;
import com.guldan.jaina.dto.projectregisterbatch.CopyBatchDataDTO;
import com.guldan.jaina.dto.projectregisterupload.ProjectRegisterUploadDTO;
import com.guldan.jaina.dto.summarybatchrelation.SummaryBatchRelationDTO;
import com.guldan.jaina.task.CopyBatchDataThread;
import com.guldan.mapper.db.entity.*;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.guldan.core.enums.AuditorTypeEn;
import com.guldan.core.enums.ProjectRegisterBatchEn;
import com.guldan.core.enums.ProjectRegisterEn;
import com.guldan.core.manager.BaseManager;
import com.guldan.core.search.Pagination;
import com.guldan.core.utils.DateUtil;
import com.guldan.jaina.dto.orgbatchsummary.OrgBatchSummaryDTO;
import com.guldan.jaina.dto.projectregisterbatch.BatchAuditorDTO;
import com.guldan.jaina.dto.projectregisterbatch.ProjectRegisterBatchDTO;
import com.guldan.jaina.dto.projectregisterbatch.ProjectRegisterBatchSearchDTO;
import com.guldan.jaina.dto.registerbatchstatics.ProjectBatchExtStatDTO;
import com.guldan.jaina.utils.ProjectRegisterBatchDomainConvertUtils;
import com.guldan.jaina.utils.UserUtils;
import com.guldan.mapper.db.dto.ProjectBatchStatDTO;
import com.guldan.mapper.db.dto.orgBatchSummary.OrgBatchSummaryExtDTO;
import com.guldan.mapper.db.mapper.ProjectRegisterBatchMapperExt;
import com.guldan.mapper.db.mapper.RegisterBatchStaticsMapperExt;
import com.guldan.mapper.db.mapper.RegisterFailMapperExt;
import com.guldan.mapper.db.mapper.RegisterSuccessMapperExt;

/**
 * Created by Silas.
 * Date: 2016/12/3
 * Time: 17:35
 */
@Service
public class ProjectRegisterBatchManager extends BaseManager {

    @Autowired
    private ProjectRegisterBatchMapperExt projectRegisterBatchMapperExt;

    @Autowired
    private RegisterSuccessMapperExt registerSuccessMapperExt;

    @Autowired
    private RegisterFailMapperExt registerFailMapperExt;

    @Autowired
    private RegisterBatchStaticsMapperExt registerBatchStaticsMapperExt;

    @Autowired
    private OrgBatchSummaryManager orgBatchSummaryManager;

    @Autowired
    private ProjectExtensionDicManager projectExtensionDicManager;

    @Autowired
    private RegisterManager registerManager;

    @Autowired
    private ProjectExtensionDetailManager projectExtensionDetailManager;

    @Autowired
    private RegisterFailManager registerFailManager;

    @Autowired
    private RegisterSuccessManager registerSuccessManager;

    @Autowired
    private ProjectRegisterUploadManager projectRegisterUploadManager;

    @Autowired
    private CitizenPropertyManager citizenPropertyManager;

    @Autowired
    private SummaryBatchRelationManager summaryBatchRelationManager;

    /*人数统计值*/
    /*public static List<Integer> successState = new ArrayList<>();
    public static List<Integer> failState = new ArrayList<>();

    static {
        //成功人数
        successState.add(ProjectRegisterEn.register_ing.getCode());
        successState.add(ProjectRegisterEn.auditor_ing.getCode());
        successState.add(ProjectRegisterEn.auditor_ed.getCode());
        successState.add(ProjectRegisterEn.org_auditor_ing.getCode());
        successState.add(ProjectRegisterEn.org_auditor_ed.getCode());
        successState.add(ProjectRegisterEn.finance_auditor_ing.getCode());
        successState.add(ProjectRegisterEn.finance_auditor_ed.getCode());
        successState.add(ProjectRegisterEn.finance_created_file.getCode());
        successState.add(ProjectRegisterEn.finance_downloaded_file.getCode());
        successState.add(ProjectRegisterEn.bank_success.getCode());

        //失败人数
        failState.add(ProjectRegisterEn.auditor_fail.getCode());
        failState.add(ProjectRegisterEn.org_auditor_fail.getCode());
        failState.add(ProjectRegisterEn.finance_auditor_fail.getCode());
        failState.add(ProjectRegisterEn.bank_fail.getCode());
    }*/

    /*乡镇人员登记*/
    //+++++++++++++++++++++++++++++++++++++++++++++++
    //列表返回乡镇人员登记,当前正在登记中的项目批次记录
    public Pagination<ProjectRegisterBatchDTO> townsRegistingList(ProjectRegisterBatchSearchDTO searchDTO) {

        List<Integer> state = new ArrayList<>();
        state.add(ProjectRegisterBatchEn.register_ing.getCode());
        searchDTO.setState(state);

        searchDTO.setCreatorAreaId(UserUtils.getUser().getAreaId());

        return searchByPage(searchDTO);
    }

    //列表返回乡镇人员登记,已经提交上报的项目批次列表
    public Pagination<ProjectRegisterBatchDTO> townsRegistedList(ProjectRegisterBatchSearchDTO searchDTO) {

        List<Integer> notState = new ArrayList<>();
        notState.add(ProjectRegisterBatchEn.register_ing.getCode());
        searchDTO.setNotState(notState);

        searchDTO.setCreatorAreaId(UserUtils.getUser().getAreaId());

        return searchByPage(searchDTO);
    }

    //列表返回乡镇人员登记,已经完结的项目批次列表
    public Pagination<ProjectRegisterBatchDTO> finishBatchList(ProjectRegisterBatchSearchDTO searchDTO) {

        List<Integer> state = new ArrayList<>();
        state.add(ProjectRegisterBatchEn.bank_success_all.getCode());
        state.add(ProjectRegisterBatchEn.bank_fail_all.getCode());
        state.add(ProjectRegisterBatchEn.bank_success_part.getCode());

        if (searchDTO.getState() == null || searchDTO.getState().size() == 0)
            searchDTO.setState(state);

        searchDTO.setCreatorAreaId(UserUtils.getUser().getAreaId());

        return searchByPage(searchDTO);
    }

    //提交登记上报
    public Boolean approvalSubmit(Integer batchId) throws BusinessException {

        Boolean ret = true;

        //数据校验
        //人数相关统计
        ProjectBatchStatDTO projectBatchStatDTO = getProjectBatchStatInfo(batchId, ProjectRegisterEn.getSuccessStateList(), ProjectRegisterEn.getFailStateList());
        if (projectBatchStatDTO == null || projectBatchStatDTO.getSuccessCount() == null || projectBatchStatDTO.getSuccessCount() == 0) {
            throw new BusinessException("登记成功人数为0，不能提交上报");
        }


        //修改批次表状态为待复核
        ProjectRegisterBatch projectRegisterBatch = projectRegisterBatchMapperExt.selectByPrimaryKey(batchId);
        projectRegisterBatch.setState(ProjectRegisterBatchEn.auditor_ing.getCode());
        projectRegisterBatch.setModifyTime(DateUtil.getCurrentTime());
        projectRegisterBatchMapperExt.updateByPrimaryKeySelective(projectRegisterBatch);

        //将处于登记中的登记记录，修改成待复核
        RegisterSuccess update = new RegisterSuccess();
        update.setState(ProjectRegisterEn.auditor_ing.getCode());
        update.setModifyTime(DateUtil.getCurrentTime());
        RegisterSuccessExample updateExample = new RegisterSuccessExample();
        RegisterSuccessExample.Criteria updateCriteria = updateExample.createCriteria();
        updateCriteria.andBatchIdEqualTo(batchId);
        updateCriteria.andIsDeleteEqualTo(false);

        List<Integer> states = new ArrayList<>();
        states.add(ProjectRegisterEn.register_ing.getCode());
        states.add(ProjectRegisterEn.auditor_fail.getCode());
        updateCriteria.andStateIn(states);
        registerSuccessMapperExt.updateByExampleSelective(update, updateExample);


        //确定主管部门org_id
        return ret;
    }

    //整体删除某个登记批次记录
    public Boolean deleteRegisterBatch(Integer batchId) {

        //标志删除批次记录
        ProjectRegisterBatch projectRegisterBatch = projectRegisterBatchMapperExt.selectByPrimaryKey(batchId);
        projectRegisterBatch.setIsDelete(true);
        projectRegisterBatch.setModifyTime(DateUtil.getCurrentTime());
        projectRegisterBatchMapperExt.updateByPrimaryKeySelective(projectRegisterBatch);

        //标志删除汇总批次，关联记录
        summaryBatchRelationManager.deleteByBatchId(batchId);

        //标志删除批次关联的登记成功人员记录
        RegisterSuccess update = new RegisterSuccess();
        update.setIsDelete(true);
        update.setModifyTime(DateUtil.getCurrentTime());
        RegisterSuccessExample example = new RegisterSuccessExample();
        RegisterSuccessExample.Criteria criteria = example.createCriteria();
        criteria.andBatchIdEqualTo(batchId);
        criteria.andIsDeleteEqualTo(false);

        registerSuccessMapperExt.updateByExampleSelective(update, example);

        return true;
    }


    /*乡镇人员复核*/
    //+++++++++++++++++++++++++++++++++++++++++++++++
    //列表返回乡镇人员复核,当前需要操作的批次列表
    public Pagination<ProjectRegisterBatchDTO> townsAuditoringList(ProjectRegisterBatchSearchDTO searchDTO) {

        List<Integer> state = new ArrayList<>();
        state.add(ProjectRegisterBatchEn.auditor_ing.getCode());
        state.add(ProjectRegisterBatchEn.auditor_ed.getCode());
        searchDTO.setState(state);

        searchDTO.setCreatorAreaId(UserUtils.getUser().getAreaId());

        return searchByPage(searchDTO);
    }

    //列表返回乡镇人员复核,复核通过的批次列表
    public Pagination<ProjectRegisterBatchDTO> townsAuditoredList(ProjectRegisterBatchSearchDTO searchDTO) {

        List<Integer> notState = new ArrayList<>();
        notState.add(ProjectRegisterBatchEn.register_ing.getCode());
        notState.add(ProjectRegisterBatchEn.auditor_ing.getCode());
        notState.add(ProjectRegisterBatchEn.auditor_ed.getCode());
        searchDTO.setNotState(notState);

        searchDTO.setCreatorAreaId(UserUtils.getUser().getAreaId());

        return searchByPage(searchDTO);
    }

    //对批次操作，复核通过、复核不通过、上报
    public Boolean townsAuditorSubmit(BatchAuditorDTO dto) {
        Boolean ret = true;
        try {

            int newState;
            RegisterSuccess update = new RegisterSuccess();
            RegisterSuccessExample updateExample = new RegisterSuccessExample();
            RegisterSuccessExample.Criteria updateCriteria = updateExample.createCriteria();


            if (dto.getAuditorType() == AuditorTypeEn.allow.getCode()) {
                //审核通过
                newState = ProjectRegisterBatchEn.auditor_ed.getCode();
                update.setState(ProjectRegisterEn.auditor_ed.getCode());
                updateCriteria.andStateEqualTo(ProjectRegisterEn.auditor_ing.getCode());
            } else if (dto.getAuditorType() == AuditorTypeEn.notallow.getCode()) {
                //审核拒绝
                newState = ProjectRegisterBatchEn.register_ing.getCode();
                update.setState(ProjectRegisterEn.auditor_fail.getCode());
                updateCriteria.andStateEqualTo(ProjectRegisterEn.auditor_ing.getCode());
            } else {
                //审核上报
                newState = ProjectRegisterBatchEn.org_auditor_ing.getCode();
                update.setState(ProjectRegisterEn.org_auditor_ing.getCode());
                updateCriteria.andStateEqualTo(ProjectRegisterEn.auditor_ed.getCode());

            }

            //修改批次表状态
            ProjectRegisterBatch projectRegisterBatch = projectRegisterBatchMapperExt.selectByPrimaryKey(dto.getBatchId());
            projectRegisterBatch.setState(newState);
            projectRegisterBatch.setFailReason(dto.getReason());
            projectRegisterBatch.setModifyTime(DateUtil.getCurrentTime());
            projectRegisterBatchMapperExt.updateByPrimaryKeySelective(projectRegisterBatch);

            //修改登记记录状态
            update.setModifyTime(DateUtil.getCurrentTime());
            updateCriteria.andBatchIdEqualTo(dto.getBatchId());
            updateCriteria.andIsDeleteEqualTo(false);
            registerSuccessMapperExt.updateByExampleSelective(update, updateExample);

        } catch (Exception ex) {
            ret = false;
            logger.error(ex.getMessage());
        }
        return ret;
    }

    //对登记记录进行操作，复核通过、复核不通过
    public Boolean townsAuditorSubmitForRegister(BatchAuditorDTO dto) {

        Boolean ret = true;
        try {

            Integer newState;
            //修改登记记录状态

            RegisterSuccess update = new RegisterSuccess();
            RegisterSuccessExample updateExample = new RegisterSuccessExample();
            RegisterSuccessExample.Criteria updateCriteria = updateExample.createCriteria();

            if (dto.getAuditorType() == AuditorTypeEn.allow.getCode()) {
                //审核通过
                newState = ProjectRegisterEn.auditor_ed.getCode();
                update.setFailReason("");
            } else {
                //审核拒绝
                newState = ProjectRegisterEn.auditor_fail.getCode();
            }


            update.setState(newState);
            update.setModifyTime(DateUtil.getCurrentTime());

            updateCriteria.andStateEqualTo(ProjectRegisterEn.auditor_ing.getCode());
            updateCriteria.andBatchIdEqualTo(dto.getBatchId());
            updateCriteria.andIsDeleteEqualTo(false);
            if (!dto.getAll()) {
                updateCriteria.andRegisterIdIn(dto.getRegisterIds());
            }
            if (StringUtils.isNotBlank(dto.getReason())) {
                update.setFailReason(dto.getReason());
            }
            registerSuccessMapperExt.updateByExampleSelective(update, updateExample);

        } catch (Exception ex) {
            ret = false;
            logger.error(ex.getMessage());
        }
        return ret;
    }


    /*主管部门审批*/
    //+++++++++++++++++++++++++++++++++++++++++++++++
    //主管部门,待审批批次列表
    public Pagination<ProjectRegisterBatchDTO> orgAuditorList(ProjectRegisterBatchSearchDTO searchDTO) {
        List<Integer> state = new ArrayList<>();
        state.add(ProjectRegisterBatchEn.org_auditor_ing.getCode());
        state.add(ProjectRegisterBatchEn.org_auditor_ed.getCode());
        searchDTO.setState(state);

        searchDTO.setOrgCode(UserUtils.getUser().getWorkOrg());

        return searchByPageForOrg(searchDTO);
    }

    //对批次进行审批，审批通过、审批不通过
    public Boolean orgAuditorApproval(BatchAuditorDTO dto) {
        Boolean ret = true;
        try {

            int newState;
            RegisterSuccess update = new RegisterSuccess();
            RegisterSuccessExample updateExample = new RegisterSuccessExample();
            RegisterSuccessExample.Criteria updateCriteria = updateExample.createCriteria();


            if (dto.getAuditorType() == AuditorTypeEn.allow.getCode()) {
                //审批通过
                newState = ProjectRegisterBatchEn.org_auditor_ed.getCode();
                update.setState(ProjectRegisterEn.org_auditor_ed.getCode());
                update.setFailReason("");
            } else {
                //审批不通过
                newState = ProjectRegisterBatchEn.auditor_ing.getCode();
                update.setState(ProjectRegisterEn.org_auditor_fail.getCode());
            }

            //修改批次表状态
            ProjectRegisterBatch projectRegisterBatch = projectRegisterBatchMapperExt.selectByPrimaryKey(dto.getBatchId());
            projectRegisterBatch.setState(newState);
            projectRegisterBatch.setModifyTime(DateUtil.getCurrentTime());
            projectRegisterBatch.setFailReason(dto.getReason());
            projectRegisterBatchMapperExt.updateByPrimaryKeySelective(projectRegisterBatch);

            //修改登记记录状态
            update.setModifyTime(DateUtil.getCurrentTime());
            updateCriteria.andStateEqualTo(ProjectRegisterEn.org_auditor_ing.getCode());
            updateCriteria.andBatchIdEqualTo(dto.getBatchId());
            updateCriteria.andIsDeleteEqualTo(false);
            registerSuccessMapperExt.updateByExampleSelective(update, updateExample);

        } catch (Exception ex) {
            ret = false;
            logger.error(ex.getMessage());
        }
        return ret;
    }

    //对登记人员记录进行审批，审批通过、审批不通过
    public Boolean orgAuditorApprovalForRegister(BatchAuditorDTO dto) {
        Boolean ret = true;
        try {

            Integer newState;


            //修改登记人员记录状态

            RegisterSuccess update = new RegisterSuccess();
            RegisterSuccessExample updateExample = new RegisterSuccessExample();
            RegisterSuccessExample.Criteria updateCriteria = updateExample.createCriteria();

            if (dto.getAuditorType() == AuditorTypeEn.allow.getCode()) {
                //审批通过
                newState = ProjectRegisterEn.org_auditor_ed.getCode();
                update.setFailReason("");
            } else {
                //审批不通过
                newState = ProjectRegisterEn.org_auditor_fail.getCode();
            }

            update.setState(newState);
            update.setModifyTime(DateUtil.getCurrentTime());

            updateCriteria.andStateEqualTo(ProjectRegisterEn.org_auditor_ing.getCode());
            updateCriteria.andBatchIdEqualTo(dto.getBatchId());
            updateCriteria.andIsDeleteEqualTo(false);
            if (!dto.getAll()) {
                updateCriteria.andRegisterIdIn(dto.getRegisterIds());
            }
            if (StringUtils.isNotBlank(dto.getReason())) {
                update.setFailReason(dto.getReason());
            }
            registerSuccessMapperExt.updateByExampleSelective(update, updateExample);

        } catch (Exception ex) {
            ret = false;
            logger.error(ex.getMessage());
        }
        return ret;
    }

    //对批次进行汇总上报
    public Boolean orgAuditorSubmit(BatchAuditorDTO dto) {

        Boolean ret = true;
        try {


            List<Integer> batchIds = dto.getBatchIds();

            if (batchIds != null && batchIds.size() > 0) {

                //创建批次汇总记录
                List<OrgBatchSummaryExtDTO> orgBatchSummaryExtDTOs = orgBatchSummaryManager.collectBatchIdForOrgSubmit(batchIds);

                for (OrgBatchSummaryExtDTO orgBatchSummaryExtDTO : orgBatchSummaryExtDTOs) {

                    String summaryId = DateUtil.toLocaleString(DateUtil.getCurrentDate(), DateUtil.YYYYMMDDHHDDSS) + "-" + RandomStringUtils.randomAlphanumeric(6);

                    OrgBatchSummaryDTO orgBatchSummaryDTO = new OrgBatchSummaryDTO();

                    orgBatchSummaryDTO.setSummaryId(summaryId);
                    orgBatchSummaryDTO.setAreaId(orgBatchSummaryExtDTO.getAreaId());
                    orgBatchSummaryDTO.setProjectId(orgBatchSummaryExtDTO.getProjectId());
                    orgBatchSummaryDTO.setPayCycleCode(orgBatchSummaryExtDTO.getPayCycleCode());
                    orgBatchSummaryDTO.setYear(orgBatchSummaryExtDTO.getYear());
                    orgBatchSummaryDTO.setSubsidyCount(orgBatchSummaryExtDTO.getSubsidyCount());
                    orgBatchSummaryDTO.setState(ProjectRegisterBatchEn.finance_auditor_ing.getCode());

                    orgBatchSummaryDTO.setOrgId(1);

                    String[] ss = orgBatchSummaryExtDTO.getBatchIds().split(",");
                    List<Integer> bb = new ArrayList<>();
                    for (String s : ss) {
                        bb.add(Integer.parseInt(s));
                    }
                    orgBatchSummaryManager.save(orgBatchSummaryDTO, bb);
                }


                //修改批次记录状态为“县财部门待审核”
                ProjectRegisterBatch update = new ProjectRegisterBatch();
                update.setState(ProjectRegisterBatchEn.finance_auditor_ing.getCode());
                update.setModifyTime(DateUtil.getCurrentTime());

                ProjectRegisterBatchExample example = new ProjectRegisterBatchExample();
                ProjectRegisterBatchExample.Criteria criteria = example.createCriteria();
                criteria.andBatchIdIn(batchIds);
                criteria.andIsDeleteEqualTo(false);
                projectRegisterBatchMapperExt.updateByExampleSelective(update, example);

                //修改登记成功记录人员状态为“县财部门待审核”
                RegisterSuccess registerSuccess = new RegisterSuccess();
                registerSuccess.setState(ProjectRegisterEn.finance_auditor_ing.getCode());
                registerSuccess.setModifyTime(DateUtil.getCurrentTime());

                RegisterSuccessExample registerSuccessExample = new RegisterSuccessExample();
                RegisterSuccessExample.Criteria registerSuccessCriteria = registerSuccessExample.createCriteria();
                registerSuccessCriteria.andBatchIdIn(batchIds);
                List<Integer> state = new ArrayList<>();
                state.add(ProjectRegisterEn.org_auditor_ing.getCode());
                state.add(ProjectRegisterEn.org_auditor_ed.getCode());
                registerSuccessCriteria.andStateIn(state);
                registerSuccessMapperExt.updateByExampleSelective(registerSuccess, registerSuccessExample);

            }

        } catch (Exception ex) {
            logger.error(ex.getMessage());
            ret = false;
        } finally {
            return ret;
        }

    }


    //common
    //***************************************************
    //build查询Example
    private ProjectRegisterBatchExample buildSearchExample(ProjectRegisterBatchSearchDTO search) {
        ProjectRegisterBatchExample example = new ProjectRegisterBatchExample();
        ProjectRegisterBatchExample.Criteria criteria = example.createCriteria();

        if (search.getBatchId() != null && search.getBatchId() > 0) {
            criteria.andBatchIdEqualTo(search.getBatchId());
        }
        if (search.getProjectId() != null && search.getProjectId() > 0) {
            criteria.andProjectIdEqualTo(search.getProjectId());
        }
        if (search.getYear() != null && search.getYear() > 0) {
            criteria.andYearEqualTo(search.getYear());
        }
        if (search.getAreaId() != null && search.getAreaId() > 0) {
            criteria.andAreaIdEqualTo(search.getAreaId());
        }
        if (search.getCreatorAreaId() != null && search.getCreatorAreaId() > 0) {
            criteria.andCreatorAreaIdEqualTo(search.getCreatorAreaId());
        }

        if (search.getState() != null && search.getState().size() > 0) {
            criteria.andStateIn(search.getState());
        }
        if (search.getNotState() != null && search.getNotState().size() > 0) {
            criteria.andStateNotIn(search.getNotState());
        }
        if (StringUtils.isNotBlank(search.getPayCycleCode())) {
            criteria.andPayCycleCodeEqualTo(search.getPayCycleCode());
        }
        if (search.getSubsidyCount() != null && search.getSubsidyCount() > 0) {
            criteria.andSubsidyCountEqualTo(search.getSubsidyCount());
        }

        criteria.andIsDeleteEqualTo(Boolean.FALSE);
        if (StringUtils.isNotBlank(search.getOrderByClause())) {
            example.setOrderByClause(search.getOrderByClause());
        } else {
            example.setOrderByClause("batch_id asc");
        }
        return example;
    }

    //分页查询批次列表
    private Pagination<ProjectRegisterBatchDTO> searchByPage(ProjectRegisterBatchSearchDTO searchDTO) {

        Pagination<ProjectRegisterBatchDTO> result = new Pagination<ProjectRegisterBatchDTO>(searchDTO.getCurrentPage(), searchDTO.getPerPage());
        ProjectRegisterBatchExample example = buildSearchExample(searchDTO);
        int total = projectRegisterBatchMapperExt.countByExample(example);
        result.setTotalCount(total);
        if (total > 0) {
            List<ProjectRegisterBatchDTO> data = new ArrayList<ProjectRegisterBatchDTO>();
            List<ProjectRegisterBatch> list = projectRegisterBatchMapperExt.selectByExampleWithPaging(example, result.getOffset(), result.getPageSize());
            for (ProjectRegisterBatch entity : list) {
                ProjectRegisterBatchDTO dto = ProjectRegisterBatchDomainConvertUtils.convert(entity);

                //人数相关统计
                ProjectBatchStatDTO projectBatchStatDTO = getProjectBatchStatInfo(entity.getBatchId(), ProjectRegisterEn.getSuccessStateList(), ProjectRegisterEn.getFailStateList());

                dto.setTotalCount(projectBatchStatDTO.getTotalCount());
                dto.setSuccessCount(projectBatchStatDTO.getSuccessCount());
                dto.setFailCount(projectBatchStatDTO.getFailCount());
                //金额统计，当前状态下成功金额
                dto.setSuccessMoney(projectBatchStatDTO.getSuccessMoney());

                dto.setRegisterFailCount(registerFailMapperExt.countRegisterFailByBatchId(entity.getBatchId()));


                //扩展属性相关统计，扩展属性为数字，比如：面积
                List<Integer> batchIds = new ArrayList<>();
                batchIds.add(entity.getBatchId());
                List<ProjectBatchStatDTO> projectBatchStatDTOs = registerBatchStaticsMapperExt.statProjectBatchExtData(batchIds, ProjectRegisterEn.getSuccessStateList());
                List<ProjectBatchExtStatDTO> projectBatchExtStatDTOs = new ArrayList<>();
                if (projectBatchStatDTOs != null && projectBatchStatDTOs.size() > 0) {
                    for (ProjectBatchStatDTO pbsDTO : projectBatchStatDTOs) {

                        ProjectBatchExtStatDTO projectBatchExtStatDTO = new ProjectBatchExtStatDTO();
                        projectBatchExtStatDTO.setBatchId(pbsDTO.getBatchId());
                        projectBatchExtStatDTO.setExtId(pbsDTO.getExtId());
                        projectBatchExtStatDTO.setExtName(pbsDTO.getExtName());
                        projectBatchExtStatDTO.setExtCalculate(pbsDTO.getExtCalculate());

                        projectBatchExtStatDTOs.add(projectBatchExtStatDTO);
                    }
                }

                dto.setExtStatList(projectBatchExtStatDTOs);
                data.add(dto);
            }
            result.setList(data);
        }
        return result;
    }

    //分页查询批次列表，for 主管部门
    private Pagination<ProjectRegisterBatchDTO> searchByPageForOrg(ProjectRegisterBatchSearchDTO searchDTO) {

        Pagination<ProjectRegisterBatchDTO> result = new Pagination<ProjectRegisterBatchDTO>(searchDTO.getCurrentPage(), searchDTO.getPerPage());
        List<Integer> areaIds = new ArrayList<>();
        if (searchDTO.getAreaId() != null && searchDTO.getAreaId() > 0) {
            areaIds = (List<Integer>) cacheService.getCache(String.format(CommonConstant.KEY_AREA, searchDTO.getAreaId()));
            areaIds.add(searchDTO.getAreaId());
        } else {
            areaIds = (List<Integer>) cacheService.getCache(String.format(CommonConstant.KEY_AREA, UserUtils.getUser().getAreaId()));
            areaIds.add(UserUtils.getUser().getAreaId());
        }
        int total = projectRegisterBatchMapperExt.orgSelectBatchListCount(searchDTO.getOrgCode(), searchDTO.getState(), areaIds, searchDTO.getProjectId() == null ? 0 : searchDTO.getProjectId(), searchDTO.getYear() == null ? 0 : searchDTO.getYear(), searchDTO.getPayCycleCode() == null ? "" : searchDTO.getPayCycleCode(), searchDTO.getSubsidyCount() == null ? 0 : searchDTO.getSubsidyCount());
        result.setTotalCount(total);
        if (total > 0) {
            List<ProjectRegisterBatchDTO> data = new ArrayList<ProjectRegisterBatchDTO>();
            List<ProjectRegisterBatch> list = projectRegisterBatchMapperExt.orgSelectBatchList(searchDTO.getOrgCode(), searchDTO.getState(), areaIds, searchDTO.getProjectId() == null ? 0 : searchDTO.getProjectId(), searchDTO.getYear() == null ? 0 : searchDTO.getYear(), searchDTO.getPayCycleCode() == null ? "" : searchDTO.getPayCycleCode(), searchDTO.getSubsidyCount() == null ? 0 : searchDTO.getSubsidyCount(), result.getOffset(), result.getPageSize());
            for (ProjectRegisterBatch entity : list) {
                ProjectRegisterBatchDTO dto = ProjectRegisterBatchDomainConvertUtils.convert(entity);

                //人数相关统计
                ProjectBatchStatDTO projectBatchStatDTO = getProjectBatchStatInfo(entity.getBatchId(), ProjectRegisterEn.getSuccessStateList(), ProjectRegisterEn.getFailStateList());

                dto.setTotalCount(projectBatchStatDTO.getTotalCount());
                dto.setSuccessCount(projectBatchStatDTO.getSuccessCount());
                dto.setFailCount(projectBatchStatDTO.getFailCount());
                //金额统计，当前状态下成功金额
                dto.setSuccessMoney(projectBatchStatDTO.getSuccessMoney());

                dto.setRegisterFailCount(registerFailMapperExt.countRegisterFailByBatchId(entity.getBatchId()));


                //扩展属性相关统计，扩展属性为数字，比如：面积
                List<Integer> batchIds = new ArrayList<>();
                batchIds.add(entity.getBatchId());
                List<ProjectBatchStatDTO> projectBatchStatDTOs = registerBatchStaticsMapperExt.statProjectBatchExtData(batchIds, ProjectRegisterEn.getSuccessStateList());
                List<ProjectBatchExtStatDTO> projectBatchExtStatDTOs = new ArrayList<>();
                if (projectBatchStatDTOs != null && projectBatchExtStatDTOs.size() > 0) {
                    for (ProjectBatchStatDTO pbsDTO : projectBatchStatDTOs) {

                        ProjectBatchExtStatDTO projectBatchExtStatDTO = new ProjectBatchExtStatDTO();
                        projectBatchExtStatDTO.setBatchId(pbsDTO.getBatchId());
                        projectBatchExtStatDTO.setExtId(pbsDTO.getExtId());
                        projectBatchExtStatDTO.setExtName(pbsDTO.getExtName());
                        projectBatchExtStatDTO.setExtCalculate(pbsDTO.getExtCalculate());

                        projectBatchExtStatDTOs.add(projectBatchExtStatDTO);
                    }
                }

                dto.setExtStatList(projectBatchExtStatDTOs);
                data.add(dto);
            }
            result.setList(data);
        }
        return result;
    }


    //统计某个批次人数统计，总登记成功人数、成功人数、失败人数
    public ProjectBatchStatDTO getProjectBatchStatInfo(Integer batchId, List<Integer> successState, List<Integer> failState) {
        List<ProjectBatchStatDTO> list = projectRegisterBatchMapperExt.statProjectBatchData(batchId, successState, failState);
        ProjectBatchStatDTO dto = new ProjectBatchStatDTO();
        if (list != null && list.size() > 0) {
            dto = list.get(0);
        }
        return dto;
    }

    //统计某个批次人数统计，总登记成功人数、成功人数、失败人数
    public ProjectBatchStatDTO getProjectBatchSummaryStatInfo(String summaryId, List<Integer> successState, List<Integer> failState) {
        List<ProjectBatchStatDTO> list = projectRegisterBatchMapperExt.statProjectBatchSummaryData(summaryId, successState, failState);
        ProjectBatchStatDTO dto = new ProjectBatchStatDTO();
        if (list != null && list.size() > 0) {
            dto = list.get(0);
        }
        return dto;
    }

    //获取单个项目登记批次信息
    public ProjectRegisterBatch get(Integer batchId) {
        return projectRegisterBatchMapperExt.selectByPrimaryKey(batchId);
    }


    //登记批次一键结转
    public Boolean copyBatchData(CopyBatchDataDTO dataDTO) {
        Boolean ret = true;

        ProjectRegisterBatch projectRegisterBatch = projectRegisterBatchMapperExt.selectByPrimaryKey(dataDTO.getBatchId());

        ProjectRegisterBatch copy = new ProjectRegisterBatch();
        copy.setProjectId(projectRegisterBatch.getProjectId());
        copy.setProjectName(projectRegisterBatch.getProjectName());
        copy.setYear(dataDTO.getYear());
        copy.setPayCycleCode(projectRegisterBatch.getPayCycleCode());
        copy.setSubsidyCount(dataDTO.getSubsidyCount());
        copy.setPayObjCode(projectRegisterBatch.getPayObjCode());
        copy.setState(ProjectRegisterBatchEn.register_ing.getCode());
        copy.setAreaId(projectRegisterBatch.getAreaId());
        copy.setAreaName(projectRegisterBatch.getAreaName());
        copy.setCreatorAreaId(projectRegisterBatch.getCreatorAreaId());
        copy.setCreateTime(DateUtil.getCurrentTime());
        // copy.setCreator();
        copy.setModifyTime(DateUtil.getCurrentTime());

        projectRegisterBatchMapperExt.insertSelective(copy);

        int newBatchId = copy.getBatchId();

        int row = registerSuccessMapperExt.copyBatchData(dataDTO.getBatchId(), newBatchId, dataDTO.getYear(), dataDTO.getSubsidyCount(), ProjectRegisterEn.getSuccessStateList());

        return ret;
    }

    //登记批次一键结转
    public BarDTO copyBatchData2(CopyBatchDataDTO dataDTO) throws BusinessException {
        Boolean ret = true;

        ProjectRegisterBatch projectRegisterBatch = projectRegisterBatchMapperExt.selectByPrimaryKey(dataDTO.getBatchId());

        //check登记批次版本
        if (dataDTO.getYear().equals(projectRegisterBatch.getYear()) && dataDTO.getSubsidyCount().equals(projectRegisterBatch.getSubsidyCount())) {
            throw new BusinessException(String.format("所选年度[%s]发放次数[%s]已经登记！", dataDTO.getYear(), dataDTO.getSubsidyCount()));
        }
        //end

        //查询批次所有登记成功的记录
        RegisterSuccessExample example = new RegisterSuccessExample();
        RegisterSuccessExample.Criteria criteria = example.createCriteria();
        criteria.andBatchIdEqualTo(dataDTO.getBatchId());
        criteria.andIsDeleteEqualTo(false);
        criteria.andStateIn(ProjectRegisterEn.getSuccessStateList());
        List<RegisterSuccess> list = registerSuccessMapperExt.selectByExample(example);

        if (list == null || list.size() == 0) {
            throw new BusinessException("登记成功人数为0的批次不可以进行转结");
        }

        ProjectRegisterBatch copy = new ProjectRegisterBatch();
        copy.setProjectId(projectRegisterBatch.getProjectId());
        copy.setProjectName(projectRegisterBatch.getProjectName());
        copy.setYear(dataDTO.getYear());
        copy.setPayCycleCode(projectRegisterBatch.getPayCycleCode());
        copy.setSubsidyCount(dataDTO.getSubsidyCount());
        copy.setPayObjCode(projectRegisterBatch.getPayObjCode());
        if (UserUtils.isTowns()) {
            copy.setState(ProjectRegisterBatchEn.register_ing.getCode());
        } else
            copy.setState(ProjectRegisterBatchEn.org_auditor_ing.getCode());
        copy.setAreaId(projectRegisterBatch.getAreaId());
        copy.setAreaName(projectRegisterBatch.getAreaName());
        copy.setCreatorAreaId(projectRegisterBatch.getCreatorAreaId());
        copy.setCreateTime(DateUtil.getCurrentTime());
        copy.setCreatorUserType(projectRegisterBatch.getCreatorUserType());
        // copy.setCreator();
        copy.setModifyTime(DateUtil.getCurrentTime());

        projectRegisterBatchMapperExt.insertSelective(copy);

        int newBatchId = copy.getBatchId();


        //deal project_register_upload
        ProjectRegisterUploadDTO uploadDto = new ProjectRegisterUploadDTO();
        uploadDto.setProjectId(copy.getProjectId());
        uploadDto.setYear(copy.getYear());
        uploadDto.setBatchId(newBatchId);
        ProjectRegisterUploadDTO uploadResultDto = projectRegisterUploadManager.save(uploadDto);


        //初始化线程变量
        String barId = String.format(CommonConstant.KEY_BAR_UPLOAD_CITIZEN_ID, String.valueOf(System.currentTimeMillis()));
        BarDTO barDTO = new BarDTO();
        LinkedBlockingQueue<RegisterSuccess> queue = new LinkedBlockingQueue<>();


        for (int i = 0; i < list.size(); i++) {
            try {
                RegisterSuccess dto = list.get(i);
                dto.setBatchId(newBatchId);
                dto.setYear(dataDTO.getYear());
                dto.setSubsidyCount(dataDTO.getSubsidyCount());
                queue.put(dto);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        //获取项目的扩展属性列表
        List<ProjectExtensionDicDTO> extensionDicDTOs = projectExtensionDicManager.listByProjectId(projectRegisterBatch.getProjectId());

        barDTO = new BarDTO(barId, UploadTypeEn.register_copy.getCode(), queue.size());

        int number = 0;
        while (number < CommonConstant.THREAD_NUMBER_UPLOAD_REGISTER) {
            if (queue.size() < CommonConstant.THREAD_MAX_RECORD_COUNT) {
                number = CommonConstant.THREAD_NUMBER_UPLOAD_REGISTER;
            }
            number++;
            String threadName = "CopyBatchDataThread-" + barId + "-" + number;

            CopyBatchDataThread thread = new CopyBatchDataThread();

            thread.setQueue(queue);
            thread.setBarDTO(barDTO);
            thread.setThreadName(threadName);
            thread.setUsersDTO(UserUtils.getUser());
            thread.setDestBatchId(newBatchId);
            thread.setUploadId(uploadResultDto.getUploadId());
            thread.setCopyBatchDataDTO(dataDTO);

            thread.setProjectExtensionDetailManager(projectExtensionDetailManager);
            thread.setRegisterSuccessMapperExt(registerSuccessMapperExt);
            thread.setProjectRegisterBatchMapperExt(projectRegisterBatchMapperExt);
            thread.setRegisterFailManager(registerFailManager);
            thread.setProjectRegisterUploadManager(projectRegisterUploadManager);
            thread.setCitizenPropertyManager(citizenPropertyManager);

            Thread t = new Thread(thread, threadName);
            t.start();
        }

        return barDTO;
    }


}
